package com.czm.art_light.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.czm.art_light.annotation.CacheWithLock;
import com.czm.art_light.annotation.DistributedLock;
import com.czm.art_light.constant.ArtErrorCodeEnum;
import com.czm.art_light.constant.CommonConsts;
import com.czm.art_light.constant.RedisConstant;
import com.czm.art_light.entity.ArtArtist;
import com.czm.art_light.entity.ArtWork;
import com.czm.art_light.exception.BusinessException;
import com.czm.art_light.mapper.*;
import com.czm.art_light.param.request.ArtArtistReqDto;
import com.czm.art_light.param.request.ArtInfoReqDto;
import com.czm.art_light.param.request.ArtWorkReqDto;
import com.czm.art_light.param.response.ArtArtistBasicInfoRespDto;
import com.czm.art_light.param.response.ArtArtistEsRespDto;
import com.czm.art_light.param.response.ArtArtistInfoRespDto;
import com.czm.art_light.param.response.ArtWorkBasicInfoRespDto;
import com.czm.art_light.service.ArtArtistService;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;


/**
 * 艺术家信息 服务类
 */
@Service
public class ArtArtistServiceImpl implements ArtArtistService {
    @Autowired
    private ArtArtistMapper artArtistMapper;

    @Autowired
    private ArtCategoryMapper artCategoryMapper;

    @Autowired
    private ArtMovementMapper artMovementMapper;

    @Autowired
    private ArtTopicMapper artTopicMapper;

    @Autowired
    private ArtWorkMapper artWorkMapper;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 获取艺术家信息
     **/
    @CacheWithLock(
            cacheName = "artArtistCache",
            key = "#artInfoReqDto.id + '::' + #artInfoReqDto.pageNum + '::' + #artInfoReqDto.pageSize",   //从参数对象提取属性
            expireTime = CommonConsts.ARTIST_CACHE_EXPIRATION_TIME,
            cacheNull = true,
            enabled = true
    )
    @Override
    public ArtArtistInfoRespDto getById(ArtInfoReqDto artInfoReqDto) {
        // 判断布隆过滤器中是否存在数据
        RBloomFilter<Integer> rBloomFilter = redissonClient.getBloomFilter(RedisConstant.ART_ARTIST_BLOOM_FILTER_KEY);
        //不存在直接返回null
        if (!rBloomFilter.contains(artInfoReqDto.getId())) {
            return null;
        }

        ArtArtist artArtist = artArtistMapper.getById(artInfoReqDto.getId());
        // 艺术家不存在
        if (artArtist == null) {
            throw new BusinessException(ArtErrorCodeEnum.ARTIST_NOT_EXIST);
        }

        //根据艺术家id查找对应的艺术作品数据
        //构建分页对象
        Page<ArtWorkBasicInfoRespDto> page = new Page<>(artInfoReqDto.getPageNum(), artInfoReqDto.getPageSize());
        ArtWorkReqDto artWorkReqDto = new ArtWorkReqDto();
        artWorkReqDto.setArtistId(artInfoReqDto.getId());
        List<ArtWork> workList = artWorkMapper.listArtWorkByParamId(page, artWorkReqDto);
        List<ArtWorkBasicInfoRespDto> artworks = new ArrayList<>();
        if (!workList.isEmpty()) {
            for (ArtWork work : workList) {
                artworks.add(ArtWorkBasicInfoRespDto.builder()
                        //作品id
                        .id(work.getId())
                        //作品名称
                        .title(work.getTitle())
                        //艺术家名称
                        .artistName(artArtist.getArtistName())
                        //作品图片
                        .primaryImageSmallUrl(work.getPrimaryImageSmallUrl())
                        .build());
            }
        }

        return ArtArtistInfoRespDto.builder()
                //艺术家id
                .id(artArtist.getId())
                //艺术家名称
                .artistName(artArtist.getArtistName())
                //艺术家简介
                .biography(artArtist.getBiography())
                //艺术家头像
                .photoUrl(artArtist.getPhotoUrl())
                //艺术家国籍
                .nationality(artArtist.getNationality())
                //艺术家的出生和逝世年份(已经逝世的情况下)，格式为YYYY-YYYY
                .birthDeathYears(artArtist.getBirthDeathYears())
                //作品列表
                .artworks(artworks)
                .build();
    }

    /**
     * 获取所有的艺术家基本信息(根据艺术话题的ID或者作品类别的ID或者作品所属的流派的ID)
     */
    @Override
    public List<ArtArtistBasicInfoRespDto> list(ArtArtistReqDto artArtistReqDto) {
        List<ArtArtistBasicInfoRespDto> allArtists = new ArrayList<>();

        if (artArtistReqDto.isFetchAll()) {
            // 如果 fetchAll 为 true，则查询所有数据，忽略分页
            List<ArtArtist> artArtistList = artArtistMapper.selectAllWithoutPage();
            for (ArtArtist artArtist : artArtistList) {
                allArtists.add(ArtArtistBasicInfoRespDto.builder()
                        //艺术家id
                        .id(artArtist.getId())
                        //艺术家名字
                        .artistName(artArtist.getArtistName())
                        .build());
            }
        } else {
            // 如果 fetchAll 为 false，则使用分页查询
            Page<ArtArtistBasicInfoRespDto> page = new Page<>(artArtistReqDto.getPageNum(), artArtistReqDto.getPageSize());
            allArtists = artArtistMapper.selectAllWithTotal(page, artArtistReqDto);
        }

        // 返回结果，如果无数据，返回空列表
        return allArtists == null ? Collections.emptyList() : allArtists;
    }

    /**
     * 查询所有的艺术家信息，将其存储到ES中
     */
    @Override
    public List<ArtArtistEsRespDto> syncArtistsToES() {
        ArrayList<ArtArtistEsRespDto> artArtistEsRespDtos = new ArrayList<>();

        //查询所有的艺术家
        List<ArtArtistBasicInfoRespDto> artistBasicInfoRespDtos = artArtistMapper.selectAll();
        //遍历所有的艺术家，查询其艺术家的作品中所有的话题名字、艺术家的作品中所有的类别名字、艺术家的作品中所有的流派名字信息
        for (ArtArtistBasicInfoRespDto artistBasicInfoRespDto : artistBasicInfoRespDtos) {
            //根据艺术家ID查询其所有的创作艺术作品
            Integer artistId = artistBasicInfoRespDto.getId();
            List<ArtWork> artWorks = artWorkMapper.listByArtistId(artistId);

            //所有的话题ID(不重复)
            HashSet<Integer> topicIdSet = new HashSet<>();
            //所有的类别ID(不重复)
            HashSet<Integer> categoryIdSet = new HashSet<>();
            //所有的流派ID(不重复)
            HashSet<Integer> movementIdSet = new HashSet<>();

            // 遍历所有作品
            for (ArtWork artWork : artWorks) {
                // 添加作品所属的类别ID
                categoryIdSet.add(artWork.getCategoryId());

                // 获取作品所属的流派ID
                movementIdSet.add(artWork.getMovementId());

                // 添加作品所属的话题ID
                topicIdSet.add(artWork.getTopicId());
            }

            // 查询所有类别名称
            List<String> categoryNames = new ArrayList<>();
            for (Integer categoryId : categoryIdSet) {
                categoryNames.add(artCategoryMapper.getById(categoryId).getCategoryName());
            }
            // 查询所有流派名称
            List<String> movementNames = new ArrayList<>();
            for (Integer movementId : movementIdSet) {
                movementNames.add(artMovementMapper.getById(movementId).getMovementName());
            }

            // 查询所有话题名称
            List<String> topicNames = new ArrayList<>();
            for (Integer topicId : topicIdSet) {
                topicNames.add(artTopicMapper.getById(topicId).getTopicName());
            }

            artArtistEsRespDtos.add(ArtArtistEsRespDto.builder()
                    // 艺术家ID
                    .id(artistBasicInfoRespDto.getId())
                    // 艺术家名称
                    .artistName(artistBasicInfoRespDto.getArtistName())
                    // 艺术家照片的URL地址
                    .photoUrl(artistBasicInfoRespDto.getPhotoUrl())
                    //艺术家国籍
                    .nationality(artistBasicInfoRespDto.getNationality())
                    //艺术家的出生和逝世年份(已经逝世的情况下)，格式为YYYY-YYYY
                    .birthDeathYears(artistBasicInfoRespDto.getBirthDeathYears())
                    //总的艺术画作品数量(不管其根据上面条件，如具体的艺术话题的ID、具体的作品类别的ID、具体的作品所属的流派的ID)
                    .totalArtworkCount(artistBasicInfoRespDto.getTotalArtworkCount())
                    // 艺术家的作品中所有的话题名字
                    .allTopicNames(topicNames)
                    //艺术家的作品中所有的类别名字
                    .allCategoryNames(categoryNames)
                    //艺术家的作品中所有的流派名字
                    .allMovementNames(movementNames)
                    .build());
        }
        return artArtistEsRespDtos;
    }

    /**
     * 查询自指定时间以来新增或修改的艺术家数据
     */
    @Override
    public List<ArtArtistEsRespDto> getModifiedArtists(LocalDateTime lastSyncTime) {
        // 查询自上次同步以来新增或修改的艺术家数据
        return artArtistMapper.selectModifiedArtists(lastSyncTime);
    }
}
